package org.sixtynine.stock.api;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.sixtynine.stock.Constants;
import org.sixtynine.stock.Constants.CommonData;
import org.sixtynine.stock.ReturnData;
import org.sixtynine.stock.api.Cse.Trades;
import org.sixtynine.stock.api.Cse.Trades.Trade;
import org.sixtynine.stock.api.sector.Cse.Sectors;
import org.sixtynine.stock.api.summary.Cse.Summaries;
import org.sixtynine.stock.api.summary.Cse.Summaries.Summary;
import org.sixtynine.stock.cache.CompanyCache;
import org.sixtynine.stock.cache.CompanyDto;
import org.sixtynine.stock.cache.CurrentShareCache;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Company;
import org.sixtynine.stock.entity.IntradaySectorData;
import org.sixtynine.stock.entity.IntradayShareData;
import org.sixtynine.stock.entity.Sector;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.IntradaySectorDataService;
import org.sixtynine.stock.service.IntradayShareDataService;
import org.sixtynine.stock.service.business.StockCalculator;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.util.DateUtil;
import org.sixtynine.stock.util.Signal;
import org.sixtynine.stock.util.StockLogger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * this will run in configured time
 * 
 * @author Thilanka
 * 
 */
@Component
public class IntradaySynchronizer {

	@Autowired
	ConnectionManager connectionManager;

	@Autowired
	GenericService genericService;

	@Autowired
	IntradayShareDataService intradayShareDataService;
	@Autowired
	IntradaySectorDataService intradaySectorDataService;

	@Autowired
	CurrentShareCache currentShareCache;

	@Autowired
	CompanyCache companyCache;

	private static final String INTRADAY_DATA = "intradaydata.xml";
	private static final String INTRADAY_DATA_SUMMARY = "intradaysummarydata.xml";

	/** check whether the system is already initialized */
	private static boolean initialized = false;

	private static Date lastDeletedDate;

	private int startHour;
	private int closeHour;
	private String holidays;

	private int apiCallWaitTime;

	private int rsiHigh;
	private int rsiLow;
	private int unusual;
	private int singnalConfig;

	private static Logger logger = Logger.getLogger(IntradaySynchronizer.class);

	@PostConstruct
	private void init() {
		logger.info("############################ Initialize the Intraday Synchronizer"
				+ System.getProperty("catalina.home"));

		try {
			List<CompanyDto> companyDtos = companyCache
					.get(Constants.COMPANY_CACHED_DATA);
			StockLogger
					.debug("######################### " + companyDtos.size());
		} catch (ExecutionException e) {
			logger.error(e.getMessage());
		}
	}

	private void clearOldData() {
		logger.debug("################### Delete old records ########################");

		// before deletions, set the last sequence
		List<BaseEntity> data = genericService.findLatestRecords(1,
				IntradayShareData.class, "time");
		for (BaseEntity baseEntity : data) {
			IntradayShareData intradayShareData = (IntradayShareData) baseEntity;
			if (intradayShareData.getSequence() > 0) {
				currentShareCache.setLastSequence(intradayShareData
						.getSequence());
			}
			break;
		}
		// delete old share data
		intradayShareDataService.deleteOldRecords();

		// delete old sector data
		List<BaseEntity> sectorData = genericService.findLatestRecords(1,
				IntradaySectorData.class, "dateTime");
		for (BaseEntity baseEntity : sectorData) {
			IntradaySectorData intradaySectoreData = (IntradaySectorData) baseEntity;
			if (intradaySectoreData.getSequence() > 0) {
				currentShareCache.setLastSectorSequence(intradaySectoreData
						.getSequence());
			}
			break;
		}

		intradaySectorDataService.deleteOldRecords();

	}

	private void initialize() {
		if (currentShareCache.isEmpty()) {
			currentShareCache.restore(null);
		}

		lastDeletedDate = CurrentShareCache.getLastDeletedDate();
	}

	private boolean checkRunningValidity() {
		boolean valid = true;

		// TODO, keep the start hour and close hour in minutes in the config
		// file
		// Ex 9 = 9*60, 14.30 = (14*60 + 30)
		logger.debug(DateUtil.getMinuteOfDay() + " - " + startHour + " - "
				+ closeHour);
		if ((DateUtil.getMinuteOfDay() < startHour)
				|| (DateUtil.getMinuteOfDay() > closeHour)) {
			valid = false;
		}

		Calendar now = Calendar.getInstance();
		if (holidays.contains(String.valueOf(now.get(Calendar.DAY_OF_WEEK)))) {
			valid = false;
		}

		return valid;
	}

	private void addSignals(IntradayShareData intradayShareData)
			throws ExecutionException {

		List<CompanyDto> companyDtos = companyCache
				.get(Constants.COMPANY_CACHED_DATA);
		CompanyDto companyDto = companyCache.get(companyDtos,
				intradayShareData._getCompanyCode());
		if (companyDto != null) {

			if (companyDto.getDailyShareData().isEmpty()) {
				return;
			}
			double rsiValue = StockCalculator
					.getBean()
					.calculateRsi(
							companyDto
									._getClosingPriceWithCurrentShare(intradayShareData));

			double sma10 = StockCalculator.getBean().calculateSmaVal(
					companyDto._getClosingPrices(), 10,
					intradayShareData.getLastTradedPrice());

			double sma20 = StockCalculator.getBean().calculateSmaVal(
					companyDto._getClosingPrices(), 20,
					intradayShareData.getLastTradedPrice());

			double sma50 = StockCalculator.getBean().calculateSmaVal(
					companyDto._getClosingPrices(), 50,
					intradayShareData.getLastTradedPrice());

			double companyAverageVol = companyDto
					.getThreeMAverageVolData(intradayShareData);

			String message = "";
			if (intradayShareData.getHigh() > companyDto.getTwelMHigh()) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.HIGH, companyDto
								._getCompanyCode(), intradayShareData
								.getLastTradedPrice(), intradayShareData
								.getShareVolume(), intradayShareData
								.getPercentageChange(), intradayShareData
								.getTurnover(), intradayShareData
								.getTradeVolume(), intradayShareData
								.getCompany().getName()));
			}
			if (intradayShareData.getLow() < companyDto.getTwelMLow()) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.LOW, companyDto
								._getCompanyCode(), intradayShareData
								.getLastTradedPrice(), intradayShareData
								.getShareVolume(), intradayShareData
								.getPercentageChange(), intradayShareData
								.getTurnover(), intradayShareData
								.getTradeVolume(), intradayShareData
								.getCompany().getName()));
			} // over bought
			if (rsiValue > rsiHigh) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.RSI_OVERBOUGHT,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName()));
			}// over sold
			if (rsiValue < rsiLow) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.RSI_OVERSOLD,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName()));

			}// unusual volume
			if (companyAverageVol > unusual) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.UNUSUAL_VOLUME,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName()));

			}
			// sma 50 crossing

			if (sma50 < intradayShareData.getLastTradedPrice() && sma50 > 0) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.SMA50_CROSSING,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName(),
								"color-green"));

			}
			if (sma50 > intradayShareData.getLastTradedPrice() && sma50 > 0) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.SMA50_CROSSING,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName(),
								"color-red"));

			}

			// sma 20 crossing
			if (sma20 < intradayShareData.getLastTradedPrice() && sma20 > 0) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.SMA20_CROSSING,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName(),
								"color-green"));

			}
			if (sma20 > intradayShareData.getLastTradedPrice() && sma20 > 0) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.SMA20_CROSSING,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName(),
								"color-red"));

			}

			// sma 10 crossing
			if (sma10 < intradayShareData.getLastTradedPrice() && sma10 > 0) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.SMA10_CROSSING,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName(),
								"color-green"));

			}
			if (sma10 < intradayShareData.getLastTradedPrice() && sma10 > 0) {
				currentShareCache.getSignals().add(
						new Signal(message, Signal.SignalType.SMA10_CROSSING,
								companyDto._getCompanyCode(), intradayShareData
										.getLastTradedPrice(),
								intradayShareData.getShareVolume(),
								intradayShareData.getPercentageChange(),
								intradayShareData.getTurnover(),
								intradayShareData.getTradeVolume(),
								intradayShareData.getCompany().getName(),
								"color-red"));

			}

		}
	}

	@Deprecated
	@SuppressWarnings("unused")
	private void loadStockTradeData() {
		ReturnData<org.sixtynine.stock.api.Cse> returnData = (ReturnData<org.sixtynine.stock.api.Cse>) connectionManager
				.getData(getRequest(ConnectionManager.DATA_TYPE_STOCK, false),
						org.sixtynine.stock.api.Cse.class);

		if (returnData._isSuccess()) {
			org.sixtynine.stock.api.Cse cse = returnData.getData();
			if (cse != null && cse.getTrades() != null) {
				if (cse.getLastsequence() > 0) {
					currentShareCache.setLastSequence(cse.getLastsequence());
				}

				Trades trades = cse.getTrades();
				if (trades != null) {
					List<Trade> tradeList = trades.getTrade();
					for (Trade trade : tradeList) {

						IntradayShareData intradayShareData = mapShareData(trade);
						if (intradayShareData != null) {
							currentShareCache.add(trade.getSymbol(),
									intradayShareData);

							// save it to database as well
							genericService.saveOrUpdate(intradayShareData);
						}
					}
					logger.debug("#################### Intraday Stock Update Done ##############");
				}
			}
		}

	}

	/**
	 * @return get the trade summary data for company
	 */
	private Map<String, IntradayShareData> getTradeSummaryData() {

		logger.debug("######################## Going to get the summary data");
		Map<String, IntradayShareData> companyTradeSummaryMap = new HashMap<String, IntradayShareData>();
		@SuppressWarnings("unchecked")
		ReturnData<org.sixtynine.stock.api.Cse> returnData = (ReturnData<org.sixtynine.stock.api.Cse>) connectionManager
				.getData(getRequest(ConnectionManager.DATA_TYPE_STOCK, false),
						org.sixtynine.stock.api.Cse.class);
		if (returnData._isSuccess()) {
			org.sixtynine.stock.api.Cse cse = returnData.getData();
			if (cse != null && cse.getTrades() != null) {
				logger.error("last sequence of intraday data "+ cse.getLastsequence() +" date and time " +cse.getMessage());
				if (cse.getLastsequence() > 0) {
					currentShareCache.setLastSequence(cse.getLastsequence());
				}

				Trades trades = cse.getTrades();
				if (trades != null) {
					List<Trade> tradeList = trades.getTrade();
					for (Trade trade : tradeList) {
						// we get only one trade per company
						if (companyTradeSummaryMap.containsKey(trade
								.getSymbol())) {
							continue;
						}

						IntradayShareData intradayShareData = mapShareData(trade);
						companyTradeSummaryMap.put(trade.getSymbol(),
								intradayShareData);
					}

				}
			}
		}

		logger.debug("###################### getTradeSummaryData :"
				+ companyTradeSummaryMap.size());
		return companyTradeSummaryMap;
	}

	private void loadStockSummaryData() {

		logger.debug("################# loadStockSummaryData ");
		Map<String, IntradayShareData> tradeSummary = getTradeSummaryData();
		// we have to wait for 1 min here
		try {
			Thread.sleep(apiCallWaitTime);
		} catch (InterruptedException e1) {
		}

		// clear the signals if a limit exceeds. TODO configure this
		if (currentShareCache.getSignals().size() > singnalConfig) {
			currentShareCache.getSignals().clear();
		}

		// List<CompanyDto> companyDtos;
		// try {
		// companyDtos = companyCache.get(Constants.COMPANY_CACHED_DATA);
		// } catch (ExecutionException e1) {
		// logger.error("Error on loading company share results");
		// return;
		// }

		logger.debug("########## Going to send the stock summary data");
		@SuppressWarnings("unchecked")
		ReturnData<org.sixtynine.stock.api.summary.Cse> returnData = (ReturnData<org.sixtynine.stock.api.summary.Cse>) connectionManager
				.getData(getRequest(ConnectionManager.DATA_TYPE_STOCK, true),
						org.sixtynine.stock.api.summary.Cse.class);
		if (returnData._isSuccess()) {
			org.sixtynine.stock.api.summary.Cse cse = returnData.getData();
			if (cse != null) {
				Summaries summaries = cse.getSummaries();
				if (summaries != null) {

					double totalVolume = 0;
					double totalTurnOver = 0;
					List<Summary> summaryList = summaries.getSummary();

					List<BaseEntity> intradayList = new ArrayList<BaseEntity>();
					for (Summary summary : summaryList) {

						IntradayShareData intradayShareData = mapShareData(summary);
						if (intradayShareData != null) {

							// if there is no trade in the day, in summary,
							// share
							// price is sent as 0.
							// in that case we dont need to add that record.
							// This means the market is closed
							if (intradayShareData.getLastTradedPrice() == 0
									|| intradayShareData.getTradeVolume() == 0) {
								continue;
							}

							IntradayShareData tradeInfo = tradeSummary
									.get(summary.getSymbol());
							if (tradeInfo != null) {
								// TODO map all the other required info
								intradayShareData.setHigh(tradeInfo.getHigh());
								intradayShareData.setLow(tradeInfo.getLow());
								intradayShareData.setSequence(tradeInfo
										.getSequence());
								
							}

							totalTurnOver += intradayShareData.getTurnover();
							totalVolume += intradayShareData.getShareVolume();

							currentShareCache.add(summary.getSymbol(),
									intradayShareData);

							try {
								addSignals(intradayShareData);
							} catch (ExecutionException e) {
								e.printStackTrace();
							}

							// save it to database as well
							// genericService.saveOrUpdate(intradayShareData);

							intradayList.add(intradayShareData);

						}

						currentShareCache.setTotalMarketVolume(totalVolume);
						currentShareCache.setTotalTurnOver(totalTurnOver);
					}
					// save the list
					genericService.saveList(intradayList);
					logger.debug("#################### Intraday Stock Update Done ##############");
				}
			}
		}

	}

	/**
	 * set the number of changes
	 */
	private void setCompanyChangeSummary() {
		int gainers = 0;
		int loosers = 0;
		int unchanged = 0;
		try {
			List<CompanyDto> companies = companyCache
					.get(Constants.COMPANY_CACHED_DATA);
			for (CompanyDto companyDto : companies) {
				IntradayShareData currentShare = currentShareCache
						.getCurrentShare(companyDto._getCompanyCode());

				if (currentShare != null && currentShare.getTradeVolume() > 0) {
					if (currentShare.getValueChange() < 0) {
						loosers++;
					} else if (currentShare.getValueChange() > 0) {
						gainers++;
					} else if (currentShare.getValueChange() == 0) {
						unchanged++;
					}
				}
			}
		} catch (ExecutionException e) {
			logger.error(e.getMessage());
		}

		currentShareCache.setNumOfGainers(gainers);
		currentShareCache.setNumOfLoosers(loosers);
		currentShareCache.setNumOfUnchanged(unchanged);

	}

	public void run() {
		logger.debug("################# RUN the IntradaySynchronizer ############");

		if (!initialized) {
			initialize();
			initialized = true;
		}

		// check whether its valid time to run
		if (!checkRunningValidity()) {
			logger.debug("###################### Market is on close, not running the Process");
			if ((DateUtil.getMinuteOfDay() < startHour)) {
				// in the morning we need to clear the signals
				CurrentShareCache.setBeforeMarketOpen(true);
				currentShareCache.clearSignals();
			} else {
				CurrentShareCache.setBeforeMarketOpen(false);
			}

			// set the number of companies which get changed
			// setCompanyChangeSummary();
			return;
		}

		CurrentShareCache.setBeforeMarketOpen(false);
		// check whether the data in past date is deleted today. if not delete
		// them
		if (lastDeletedDate == null
				|| !DateUtil.isSameDay(lastDeletedDate, new Date())) {
			clearOldData();
			lastDeletedDate = new Date();
		}

		if (currentShareCache.isEmpty()) {
			try {
				List<CompanyDto> companyDtos = companyCache
						.get(Constants.COMPANY_CACHED_DATA);
				currentShareCache.restore(companyDtos);
			} catch (ExecutionException e) {
				logger.error(e.getMessage());
			}
		}

		// loading stock summary
		loadStockSummaryData();
		try {
			Thread.sleep(apiCallWaitTime);
		} catch (InterruptedException e1) {
		}

		// loading sector data
		loadSectorData();

		// set the number of companied which get changed
		setCompanyChangeSummary();

	}

	private void loadSectorData() {
		logger.debug("###################### going to load sector data");
		ReturnData<org.sixtynine.stock.api.sector.Cse> stockReturnData = (ReturnData<org.sixtynine.stock.api.sector.Cse>) connectionManager
				.getData(getRequest(ConnectionManager.DATA_TYPE_SECTOR, false),
						org.sixtynine.stock.api.sector.Cse.class);
		if (stockReturnData._isSuccess()) {
			org.sixtynine.stock.api.sector.Cse cse = stockReturnData.getData();
			if (cse != null) {
				currentShareCache.setLastSectorSequence(cse.getLastsequence());

				Sectors sectors = cse.getSectors();
				if (sectors != null) {
					List<org.sixtynine.stock.api.sector.Cse.Sectors.Sector> sectorList = sectors
							.getSector();
					List<BaseEntity> list = new ArrayList<BaseEntity>();
					for (org.sixtynine.stock.api.sector.Cse.Sectors.Sector sector : sectorList) {

						IntradaySectorData intradaySectorData = mapSectorData(sector);
						if (intradaySectorData != null) {
							currentShareCache.add(sector.getSymbol(),
									intradaySectorData);

							// save it to database as well
							// genericService.saveOrUpdate(intradaySectorData);
							list.add(intradaySectorData);
						}
					}
					// save the list at batches
					genericService.saveList(list);
					logger.debug("#################### Intraday Sector Update Done ##############");
				}
			}
		}

	}

	private IntradayShareData mapShareData(Trade trade) {
		IntradayShareData intradayShareData = new IntradayShareData();

		Company company = (Company) DataManagerService.getData(
				CommonData.COMPANY.toString(), trade.getSymbol());

		// wrong company code
		if (company == null) {
			logger.debug("------------------ " + trade.getSymbol()
					+ " missing in the database");
			return null;
		}
		intradayShareData.setCompany(company);
		intradayShareData.setHigh(trade.getHigh());
		intradayShareData.setLow(trade.getLow());
		intradayShareData.setLastTradedPrice(trade.getPrice());
		intradayShareData.setPercentageChange(trade.getPercentageChange());
		intradayShareData.setSequence(trade.getSequence());
		intradayShareData.setTradeVolume(trade.getVolume());
		intradayShareData.setValueChange(trade.getChange());

		// if there is an error, set the current time
		try {
			intradayShareData.setTime(DateUtil.getApiDate(trade.getTime()));
		} catch (ParseException e) {
			intradayShareData.setTime(new Date());
		}

		return intradayShareData;
	}

	private IntradayShareData mapShareData(Summary summary) {
		IntradayShareData intradayShareData = new IntradayShareData();

		Company company = (Company) DataManagerService.getData(
				CommonData.COMPANY.toString(), summary.getSymbol());

		// wrong company code
		if (company == null) {
			logger.debug("------------------ " + summary.getSymbol()
					+ " missing in the database");
			return null;
		}
		intradayShareData.setCompany(company);
		intradayShareData.setLastTradedPrice(summary.getLastTradedPrice());
		intradayShareData.setPercentageChange(summary.getPercentageChange());
		intradayShareData.setTradeVolume(summary.getTradeVolume());
		intradayShareData.setValueChange(summary.getChange());

		intradayShareData.setTurnover(summary.getTurnover());
		intradayShareData.setClosingPrice(summary.getClosingPrice());
		intradayShareData.setPreviousClose(summary.getPreviousClose());
		intradayShareData.setShareVolume(summary.getShareVolume());

		intradayShareData.setTime(new Date());

		return intradayShareData;
	}

	private IntradaySectorData mapSectorData(
			org.sixtynine.stock.api.sector.Cse.Sectors.Sector apiSector) {
		IntradaySectorData intradaySectorData = new IntradaySectorData();

		Sector sector = (Sector) DataManagerService.getData(
				CommonData.SECTOR.toString(), apiSector.getSymbol());

		// wrong company code
		if (sector == null) {
			logger.debug("------------------ " + apiSector.getSymbol()
					+ " missing in the database");
			return null;
		}

		intradaySectorData.setSector(sector);
		intradaySectorData.setPercentageChange(apiSector.getPercentageChange());
		intradaySectorData.setValue(apiSector.getValue());
		intradaySectorData.setValueChange(apiSector.getChange());

		// if there is an error, set the current time
		try {
			intradaySectorData.setDateTime(DateUtil.getApiDate(apiSector
					.getTime()));
		} catch (ParseException e) {
			intradaySectorData.setDateTime(new Date());
		}

		return intradaySectorData;
	}

	protected String getRequest(int type, boolean summary) {
		StringBuilder requestBuilder = new StringBuilder();

		if (summary) {
			requestBuilder.append(INTRADAY_DATA_SUMMARY);
		} else {
			requestBuilder.append(INTRADAY_DATA);
		}

		// need all items
		requestBuilder.append("?TYPE=" + type);
		requestBuilder.append("&SOURCE=" + ConnectionManager.DATA_SOURCE_RAW);
		requestBuilder.append("&ITEMID=*");

		if (!summary) {
			// different last sequences for different types
			if (type == ConnectionManager.DATA_TYPE_STOCK) {
				if (currentShareCache.getLastSequence() != null) {
					requestBuilder.append("&LASTSEQUENCE="
							+ currentShareCache.getLastSequence());
				}
			} else {
				if (CurrentShareCache.getLastSectorSequence() != null) {
					requestBuilder.append("&LASTSEQUENCE="
							+ CurrentShareCache.getLastSectorSequence());
				}
			}
		}

		return requestBuilder.toString();
	}

	public static Date getLastDeletedDate() {
		return lastDeletedDate;
	}

	public static void setLastDeletedDate(Date lastDeletedDate) {
		IntradaySynchronizer.lastDeletedDate = lastDeletedDate;
	}

	public int getStartHour() {
		return startHour;
	}

	public void setStartHour(int startHour) {
		this.startHour = startHour;
	}

	public int getCloseHour() {
		return closeHour;
	}

	public void setCloseHour(int closeHour) {
		this.closeHour = closeHour;
	}

	public String getHolidays() {
		return holidays;
	}

	public void setHolidays(String holidays) {
		this.holidays = holidays;
	}

	public int getApiCallWaitTime() {
		return apiCallWaitTime;
	}

	public void setApiCallWaitTime(int apiCallWaitTime) {
		this.apiCallWaitTime = apiCallWaitTime;
	}

	public int getRsiHigh() {
		return rsiHigh;
	}

	public void setRsiHigh(int rsiHigh) {
		this.rsiHigh = rsiHigh;
	}

	public int getRsiLow() {
		return rsiLow;
	}

	public void setRsiLow(int rsiLow) {
		this.rsiLow = rsiLow;
	}

	public int getUnusual() {
		return unusual;
	}

	public void setUnusual(int unusual) {
		this.unusual = unusual;
	}

	public int getSingnalConfig() {
		return singnalConfig;
	}

	public void setSingnalConfig(int singnalConfig) {
		this.singnalConfig = singnalConfig;
	}

}
